package com.it.schoolhomeos.service.impl;

import com.it.schoolhomeos.entity.ClassInfo;
import com.it.schoolhomeos.entity.Notification;
import com.it.schoolhomeos.entity.User;
import com.it.schoolhomeos.enums.NotificationStatus;
import com.it.schoolhomeos.enums.NotificationTargetRole;
import com.it.schoolhomeos.enums.NotificationType;
import com.it.schoolhomeos.repository.ClassInfoRepository;
import com.it.schoolhomeos.repository.NotificationRepository;
import com.it.schoolhomeos.repository.UserRepository;
import com.it.schoolhomeos.service.NotificationService;
import com.it.schoolhomeos.util.FileUploadUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 通知服务实现类
 */
@Service
public class NotificationServiceImpl implements NotificationService {
    
    @Autowired
    private NotificationRepository notificationRepository;
    
    @Autowired
    private ClassInfoRepository classInfoRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private FileUploadUtil fileUploadUtil;
    
    @Override
    @Transactional
    public Notification createNotification(Notification notification, List<MultipartFile> attachments, MultipartFile coverImage) {
        // 设置创建时间和更新时间
        LocalDateTime now = LocalDateTime.now();
        notification.setCreateTime(now);
        notification.setUpdateTime(now);
        
        // 如果是已发布状态，设置发布时间
        if (notification.getStatus() == NotificationStatus.PUBLISHED) {
            notification.setPublishTime(now);
        }
        
        // 处理附件上传
        if (attachments != null && !attachments.isEmpty()) {
            List<String> attachmentUrls = uploadAttachments(attachments);
            notification.setAttachments(String.join(",", attachmentUrls));
        }
        
        // 处理封面图片上传
        if (coverImage != null && !coverImage.isEmpty()) {
            String coverImageUrl = fileUploadUtil.uploadFile(coverImage, "notification/cover");
            notification.setCoverImage(coverImageUrl);
        }
        
        return notificationRepository.save(notification);
    }
    
    @Override
    @Transactional
    public Notification updateNotification(Notification notification, List<MultipartFile> attachments, MultipartFile coverImage) {
        Notification existingNotification = notificationRepository.findById(notification.getId())
                .orElseThrow(() -> new RuntimeException("通知不存在"));
        
        // 更新基本信息
        existingNotification.setTitle(notification.getTitle());
        existingNotification.setContent(notification.getContent());
        existingNotification.setType(notification.getType());
        existingNotification.setTargetRole(notification.getTargetRole());
        existingNotification.setClassInfo(notification.getClassInfo());
        existingNotification.setIsTop(notification.getIsTop());
        existingNotification.setStatus(notification.getStatus());
        existingNotification.setUpdateTime(LocalDateTime.now());
        
        // 如果状态从草稿变为已发布，设置发布时间
        if (existingNotification.getStatus() == NotificationStatus.PUBLISHED && 
                existingNotification.getPublishTime() == null) {
            existingNotification.setPublishTime(LocalDateTime.now());
        }
        
        // 处理附件上传
        if (attachments != null && !attachments.isEmpty()) {
            List<String> attachmentUrls = uploadAttachments(attachments);
            
            // 如果已有附件，则追加新附件
            if (existingNotification.getAttachments() != null && !existingNotification.getAttachments().isEmpty()) {
                String existingAttachments = existingNotification.getAttachments();
                existingNotification.setAttachments(existingAttachments + "," + String.join(",", attachmentUrls));
            } else {
                existingNotification.setAttachments(String.join(",", attachmentUrls));
            }
        }
        
        // 处理封面图片上传
        if (coverImage != null && !coverImage.isEmpty()) {
            String coverImageUrl = fileUploadUtil.uploadFile(coverImage, "notification/cover");
            existingNotification.setCoverImage(coverImageUrl);
        }
        
        return notificationRepository.save(existingNotification);
    }
    
    @Override
    public Notification getNotificationById(Long id) {
        return notificationRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("通知不存在"));
    }
    
    @Override
    @Transactional
    public void deleteNotification(Long id) {
        notificationRepository.deleteById(id);
    }
    
    @Override
    public Page<Notification> getNotificationsByTypeAndStatus(
            NotificationType type, NotificationStatus status, Pageable pageable) {
        if (type == null) {
            if (status == null) {
                return notificationRepository.findAllByOrderByIsTopDescCreateTimeDesc(pageable);
            }
            return notificationRepository.findByStatusOrderByIsTopDescCreateTimeDesc(status, pageable);
        }
        
        if (status == null) {
            return notificationRepository.findByTypeOrderByIsTopDescCreateTimeDesc(type, pageable);
        }
        return notificationRepository.findByTypeAndStatusOrderByIsTopDescCreateTimeDesc(type, status, pageable);
    }
    
    @Override
    public Page<Notification> getNotificationsByTypeAndStatusAndTargetRole(
            NotificationType type, NotificationStatus status, NotificationTargetRole targetRole, Pageable pageable) {
        return notificationRepository.findByTypeAndStatusAndTargetRoleOrderByIsTopDescCreateTimeDesc(
                type, status, targetRole, pageable);
    }
    
    @Override
    public Page<Notification> getNotificationsByTypeAndStatusAndClassId(
            NotificationType type, NotificationStatus status, Long classId, Pageable pageable) {
        return notificationRepository.findByTypeAndStatusAndClassId(type, status, classId, pageable);
    }
    
    @Override
    public List<Notification> getTopNotifications(NotificationStatus status) {
        return notificationRepository.findByIsTopTrueAndStatusOrderByCreateTimeDesc(status);
    }
    
    @Override
    public Page<Notification> searchNotificationsByTitle(String title, NotificationStatus status, Pageable pageable) {
        return notificationRepository.findByTitleContainingAndStatusOrderByIsTopDescCreateTimeDesc(
                title, status, pageable);
    }
    
    @Override
    public Page<Notification> getAllNotifications(Pageable pageable) {
        return notificationRepository.findAllByOrderByIsTopDescCreateTimeDesc(pageable);
    }
    
    @Override
    @Transactional
    public Notification setNotificationTopStatus(Long id, Boolean isTop) {
        Notification notification = notificationRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("通知不存在"));
        notification.setIsTop(isTop);
        notification.setUpdateTime(LocalDateTime.now());
        return notificationRepository.save(notification);
    }
    
    @Override
    @Transactional
    public Notification updateNotificationStatus(Long id, NotificationStatus status) {
        Notification notification = notificationRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("通知不存在"));
        notification.setStatus(status);
        notification.setUpdateTime(LocalDateTime.now());
        
        // 如果状态变为已发布，设置发布时间
        if (status == NotificationStatus.PUBLISHED && notification.getPublishTime() == null) {
            notification.setPublishTime(LocalDateTime.now());
        }
        
        return notificationRepository.save(notification);
    }
    
    /**
     * 上传附件文件
     * 
     * @param attachments 附件文件列表
     * @return 附件URL列表
     */
    private List<String> uploadAttachments(List<MultipartFile> attachments) {
        List<String> attachmentUrls = new ArrayList<>();
        for (MultipartFile attachment : attachments) {
            if (!attachment.isEmpty()) {
                String attachmentUrl = fileUploadUtil.uploadFile(attachment, "notification/attachment");
                attachmentUrls.add(attachmentUrl);
            }
        }
        return attachmentUrls;
    }
} 